#ifndef _WX_CSHELP_H_
#define _WX_CSHELP_H_

#include "wx/defs.h"
#include "wx/help.h"

#include "wx/hashmap.h"
#if wxUSE_BMPBUTTON
#include "wx/bmpbuttn.h"
#endif

#include "wx/event.h"

class wxContextHelp : public wxObject {
  public:
    wxContextHelp( wxWindow* win = NULL, bool beginHelp = true );
    virtual ~wxContextHelp();

    bool BeginContextHelp( wxWindow* win );
    bool EndContextHelp();

    bool EventLoop();
    bool DispatchEvent( wxWindow* win, const wxPoint& pt );

    void SetStatus( bool status ) { m_status = status; }

  protected:
    bool    m_inHelp;
    bool    m_status; // true if the user left-clicked

  private:
    DECLARE_DYNAMIC_CLASS( wxContextHelp )
};

#if wxUSE_BMPBUTTON

class wxContextHelpButton : public wxBitmapButton {
  public:
    wxContextHelpButton( wxWindow* parent,
                         wxWindowID id = wxID_CONTEXT_HELP,
                         const wxPoint& pos = wxDefaultPosition,
                         const wxSize& size = wxDefaultSize,
                         long style = wxBU_AUTODRAW );

    void OnContextHelp( wxCommandEvent& event );

  private:
    DECLARE_DYNAMIC_CLASS_NO_COPY( wxContextHelpButton )
    DECLARE_EVENT_TABLE()
};

#endif

class wxHelpProvider {
  public:
    static wxHelpProvider *Set( wxHelpProvider *helpProvider ) {
      wxHelpProvider *helpProviderOld = ms_helpProvider;
      ms_helpProvider = helpProvider;
      return helpProviderOld;
    }
    static wxHelpProvider *Get() { return ms_helpProvider; }
    virtual wxString GetHelp( const wxWindowBase *window ) = 0;
    virtual bool ShowHelpAtPoint( wxWindowBase *window,const wxPoint& pt,wxHelpEvent::Origin origin ) {
      wxCHECK_MSG( window, false, wxT( "window must not be NULL" ) );
      m_helptextAtPoint = pt;
      m_helptextOrigin = origin;
      return ShowHelp( window );
    }
    virtual bool ShowHelp( wxWindowBase * ( window ) ) { return false; }
    virtual void AddHelp( wxWindowBase *window, const wxString& text );
    virtual void AddHelp( wxWindowID id, const wxString& text );
    virtual void RemoveHelp( wxWindowBase* window );
    virtual ~wxHelpProvider();
  protected:
    wxHelpProvider()
      : m_helptextAtPoint( wxDefaultPosition ),
        m_helptextOrigin( wxHelpEvent::Origin_Unknown ) {
    }
    wxString GetHelpTextMaybeAtPoint( wxWindowBase *window );
    wxPoint m_helptextAtPoint;
    wxHelpEvent::Origin m_helptextOrigin;
  private:
    static wxHelpProvider *ms_helpProvider;
};

WX_DECLARE_EXPORTED_HASH_MAP( wxUIntPtr, wxString, wxIntegerHash,wxIntegerEqual, wxSimpleHelpProviderHashMap );

class wxSimpleHelpProvider : public wxHelpProvider {
  public:
    virtual wxString GetHelp( const wxWindowBase *window );
    virtual bool ShowHelp( wxWindowBase *window );
    virtual void AddHelp( wxWindowBase *window, const wxString& text );
    virtual void AddHelp( wxWindowID id, const wxString& text );
    virtual void RemoveHelp( wxWindowBase* window );
  protected:
    wxSimpleHelpProviderHashMap m_hashWindows,m_hashIds;
};

class wxHelpControllerHelpProvider : public wxSimpleHelpProvider {
  public:
    wxHelpControllerHelpProvider( wxHelpControllerBase* hc = ( wxHelpControllerBase* ) NULL );
    virtual bool ShowHelp( wxWindowBase *window );
    void SetHelpController( wxHelpControllerBase* hc ) { m_helpController = hc; }
    wxHelpControllerBase* GetHelpController() const { return m_helpController; }

  protected:
    wxHelpControllerBase*   m_helpController;

    DECLARE_NO_COPY_CLASS( wxHelpControllerHelpProvider )
};

 wxString wxContextId( int id );

#endif
